<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>
<body>
    <input type="text" id="input">
    <div id="btn">
        
    </div>
</body>
<script>
    function getById(id){
        return document.getElementById(id)
    }
    let data = {
    a:getById('input').value,
}
getById('input').oninput=()=>{
    data.a = getById('input').value;
}
getById('btn').innerHTML = data.a;

let target = null;
// class Responsive {
//   constructor() {
//     this.target = null;
//   }
//   receive(data) {
//     Object.keys(data).forEach(item => {
//       let oldvalue = data[item];
//       let dep = new Dep(this.target);
//       Object.defineProperty(data, item, {
//         get: () => {
//           dep.collect();
//           return oldvalue;
//         },
//         set: value => {
//           oldvalue = value;
//           dep.updated();
//         }
//       });
//     });
//   }
//   Watch(func) {
//     this.target = func;
//     this.target();
//     this.target = null;
//   }
//   render(data,func) {
//     this.receive(data);
//     this.Watch(func);
//   }
// }

class Dep {
  constructor() {
    this.subscribe = [];

  }
  collect() {
    if (target && !this.subscribe.includes(target)) {
      this.subscribe.push(target);
    }
  }
  updated() {
    this.subscribe.forEach(item => {
      item();
    });
  }
}

function Receive(data){
    Object.keys(data).forEach((item)=>{
        let oldvalue = data[item];
        let dep = new Dep();
        Object.defineProperty(data,item,{
            get:()=>{
                dep.collect();
                return oldvalue;
            },
            set:(value)=>{
                oldvalue = value;
                dep.updated();
            }
        })
     })
}
Receive(data)
function Watch(func){
    target = func;
    target()
    target = null;
}
Watch(()=>{
    getById('btn').innerHTML = data.a;
})

</script>
</html>